#include "BucketsMeta.h"
#include "../../common/YXConstant.h"
#include "../../common/YXFile.h"
#include "../../common/YXIO.h"
#include "../../common/YXTime.h"
#include "../../utils/BucketsAccess.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int bucket_global_meta_create_meta() {
    char *fullpath = malloc(sizeof(BUCKET_META_PREFIX_PATH) + sizeof(BUCKET_META_GLOBAL_FILE_SUFFIX_PATH));
    sprintf(fullpath, "%s%s", BUCKET_META_PREFIX_PATH, BUCKET_META_GLOBAL_FILE_SUFFIX_PATH);

    FILE *fp = yx_file_open(fullpath, "a");
    if (fp == NULL) {
        return YX_ERR;
    }
    fclose(fp);

    return YX_OK;
}

/**
 * 设置全局元数据
 * 暂时来说全局元数据只存所有的桶名
 */
int bucket_global_meta_set_str_meta(char *value) {
    char *fullpath = malloc(sizeof(BUCKET_META_PREFIX_PATH) + sizeof(BUCKET_META_GLOBAL_FILE_SUFFIX_PATH));
    sprintf(fullpath, "%s%s", BUCKET_META_PREFIX_PATH, BUCKET_META_GLOBAL_FILE_SUFFIX_PATH);

    FILE *fp = yx_file_open(fullpath, "ab");
    if (fp == NULL) {
        return YX_ERR;
    }
    fprintf(fp, "%s\n", value);
    fclose(fp);

    return YX_OK;
}

/**
 * 获取所有的桶
 * @note 返回的 sds* 调用 sds_free_split 释放内存
 */
sds *bucket_global_meta_get_all_buckets(int *bucket_cnt) {
    char *fullpath = malloc(sizeof(BUCKET_META_PREFIX_PATH) + sizeof(BUCKET_META_GLOBAL_FILE_SUFFIX_PATH));
    sprintf(fullpath, "%s%s", BUCKET_META_PREFIX_PATH, BUCKET_META_GLOBAL_FILE_SUFFIX_PATH);

    sds buf = sds_create_empty(128);
    file_read_all(fullpath, &buf);


    return sds_split(buf, sds_len(buf), "\n", 1, bucket_cnt);
}

int bucket_meta_create_meta_file(char *bucket) {
    char *fullpath =
            malloc(sizeof(BUCKET_META_PREFIX_PATH) + sizeof(BUCKET_META_ALONE_FILE_SUFFIX_PATH) + strlen(bucket));
    sprintf(fullpath, "%s%s%s", BUCKET_META_PREFIX_PATH, bucket, BUCKET_META_ALONE_FILE_SUFFIX_PATH);

    FILE *fp = yx_file_open(fullpath, "w");
    if (fp == NULL) {
        return YX_ERR;
    }
    // 写入创建时间
    fprintf(fp, "%s", yx_time_get_local_date_time());
    // 写入默认访问策略
    fprintf(fp, "%c", BUCKET_DEFAULT_ACCESS_POLICY);

    fclose(fp);

    return YX_OK;
}

int bucket_meta_remove_meta_file(char *bucket) {
    char *fullpath =
            malloc(sizeof(BUCKET_META_PREFIX_PATH) + sizeof(BUCKET_META_ALONE_FILE_SUFFIX_PATH) + strlen(bucket));
    sprintf(fullpath, "%s%s%s", BUCKET_META_PREFIX_PATH, bucket, BUCKET_META_ALONE_FILE_SUFFIX_PATH);
    return remove(fullpath);
}

char *bucket_meta_get_str_meta(char *bucket, char *key) {
    char *fullpath =
            malloc(sizeof(BUCKET_META_PREFIX_PATH) + sizeof(BUCKET_META_ALONE_FILE_SUFFIX_PATH) + strlen(bucket));
    sprintf(fullpath, "%s%s%s", BUCKET_META_PREFIX_PATH, bucket, BUCKET_META_ALONE_FILE_SUFFIX_PATH);

    FILE *fp = fopen(fullpath, "rb");
    if (fp == NULL) {
        return NULL;
    }

    int pos, length;
    if (strcmp(key, "created_time") == 0) {
        pos    = BUCKET_META_1_CREATED_TIME_POS;
        length = BUCKET_META_1_CREATED_TIME_LENGTH;
    } else {
        return NULL;
    }

    fseek(fp, pos, SEEK_SET);
    char *value = malloc(length + 1);
    fread(value, length, 1, fp);
    value[length] = '\0';

    fclose(fp);

    return value;
}

int bucket_meta_get_constant_meta(char *bucket, char *key) {
    char *fullpath =
            malloc(sizeof(BUCKET_META_PREFIX_PATH) + sizeof(BUCKET_META_ALONE_FILE_SUFFIX_PATH) + strlen(bucket));
    sprintf(fullpath, "%s%s%s", BUCKET_META_PREFIX_PATH, bucket, BUCKET_META_ALONE_FILE_SUFFIX_PATH);

    FILE *fp = fopen(fullpath, "rb");
    if (fp == NULL) {
        return YX_ERR;
    }

    int pos, value;
    if (strcmp(key, "access_policy") == 0) {
        pos = BUCKET_META_2_ACCESS_POLICY_POS;
    } else {
        return YX_ERR;
    }
    fseek(fp, pos, SEEK_SET);
    value = fgetc(fp);

    fclose(fp);

    return value;
}